/// @tags: SAM VirtualTree
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

namespace BlueQuantum {

typedef long long LL;

int constexpr N = 2e5 + 5, SAMN = N * 2, M = 26, ST = 20;

int n, q, samcnt = 1;
int link[SAMN], ch[SAMN][M], len[SAMN], pos[N];
char s[N];

template <size_t SIZ, bool Directed>
struct Graph {
  struct Edge {
    int v, nxt;
  };

  int ecnt;
  int heads[SIZ];
  Edge e[Directed ? SIZ : SIZ * 2];

  inline int &operator()(int index) { return heads[index]; }
  inline Edge &operator[](int index) { return e[index]; }

  inline void add(int u, int v) {
    e[++ecnt].v = v, e[ecnt].nxt = heads[u], heads[u] = ecnt;
  }
};

Graph<SAMN, true> G, VG;

inline int extend(int c) {
  static int lst = 1;
  int cur = ++samcnt, pos = lst;
  lst = cur;
  len[cur] = len[pos] + 1;
  while (pos != 0 && ch[pos][c] == 0) ch[pos][c] = cur, pos = link[pos];
  if (pos == 0) return link[cur] = 1, cur;
  int q = ch[pos][c];
  if (len[q] == len[pos] + 1) return link[cur] = q, cur;
  int nq = ++samcnt;
  memcpy(ch[nq], ch[q], sizeof(ch[nq]));
  link[nq] = link[q];
  len[nq] = len[pos] + 1;
  link[q] = link[cur] = nq;
  while (pos != 0 && ch[pos][c] == q) ch[pos][c] = nq, pos = link[pos];
  return cur;
}

int dcnt;
int st[ST][SAMN * 2], dep[SAMN], dfn[SAMN], lg[SAMN * 2];

inline int cmp(int a, int b) { return dep[a] < dep[b] ? a : b; }

void dfs(int u, int fa) {
  st[0][dfn[u] = ++dcnt] = u;
  for (int i = G(u), v; i; i = G[i].nxt) {
    if ((v = G[i].v) != fa) {
      dep[v] = dep[u] + 1;
      dfs(v, u);
      st[0][++dcnt] = u;
    }
  }
}

inline int getLCA(int x, int y) {
  x = dfn[x], y = dfn[y];
  if (x > y) swap(x, y);
  int k = lg[y - x + 1];
  return cmp(st[k][x], st[k][y - (1 << k) + 1]);
}

int key[N * 2], stk[N * 2], sizA[SAMN], sizB[SAMN];

LL solve(int u) {
  LL res = ((LL)sizA[u] * sizB[u]) * len[u];
  for (int i = VG(u), v; i; i = VG[i].nxt) {
    res += solve(v = VG[i].v);
    res += ((LL)sizA[u] * sizB[v] + (LL)sizB[u] * sizA[v]) * len[u];
    sizA[u] += sizA[v];
    sizB[u] += sizB[v];
    sizA[v] = sizB[v] = 0;
  }
  return res;
}

inline int main() {
  cin >> n >> q >> (s + 1);
  for (int i = n; i >= 1; --i) {
    pos[i] = extend(s[i] - 'a');
  }
  for (int i = 2; i <= samcnt; ++i) G.add(link[i], i);
  dfs(1, 1);
  for (int i = 2; i <= dcnt; ++i) lg[i] = lg[i / 2] + 1;
  for (int i = 1, len = 2; i <= lg[dcnt]; ++i, len <<= 1) {
    for (int j = 1; j + len - 1 <= dcnt; ++j) {
      st[i][j] = cmp(st[i - 1][j], st[i - 1][j + len / 2]);
    }
  }
  for (int i = 1, k, l; i <= q; ++i) {
    cin >> k >> l;
    for (int j = 1, x; j <= k; ++j) {
      cin >> x;
      key[j] = pos[x];
    }
    for (int j = 1, x; j <= l; ++j) {
      cin >> x;
      key[j + k] = pos[x];
    }
    sizA[1] = sizB[1] = 0;
    for (int j = 1; j <= k; ++j) sizA[key[j]] = 1;
    for (int j = k + 1, jlim = k + l; j <= jlim; ++j) sizB[key[j]] = 1;
    sort(key + 1, key + k + l + 1);
    *key = unique(key + 1, key + k + l + 1) - key - 1;
    sort(key + 1, key + *key + 1, [](int a, int b) { return dfn[a] < dfn[b]; });
    int top = 1;
    stk[1] = 1;
    VG(1) = 0;
    for (int j = 1; j <= *key; ++j) {
      int LCA = getLCA(stk[top], key[j]);
      if (LCA != stk[top]) {
        while (dfn[stk[top - 1]] > dfn[LCA]) VG.add(stk[top - 1], stk[top]), top--;
        if (dfn[LCA] != dfn[stk[top - 1]])
          VG(LCA) = 0, VG.add(LCA, stk[top]), stk[top] = LCA;
        else
          VG.add(LCA, stk[top--]);
      }
      VG(key[j]) = 0, stk[++top] = key[j];
    }
    for (int j = 1; j < top; ++j) VG.add(stk[j], stk[j + 1]);
    cout << solve(1) << '\n';
  }
  return 0;
}

}  // namespace BlueQuantum

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("CF1073G Yet Another LCP Problem.in", "r", stdin);
  freopen("CF1073G Yet Another LCP Problem.out", "w", stdout);
#endif
#endif

  ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
  return BlueQuantum::main();
}
